package com.qf.service.impl;

import com.qf.pojo.Order;
import com.qf.service.OrderService;
import com.qf.service.UserService;
import org.apache.dubbo.config.annotation.Reference;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;

@Service
public class UserServiceImpl implements UserService {

    //注入一个远程的业务对象，是哟个dubbo中的@Reference
    /**
     * ① 在启动时，会将zookeeper注册中心该接口对应的提供者信息获取到（就相当于知道了远程服务器的协议、ip、端口以及接口的相关信息）
     *  会在当前应用中生成一代理对象，这个代理对象中会对这个接口的所有方法形成代理，这个代理的实现就是利用netty发起远程访问
     *
     * ② 将这个生成的代理对象添加到当前应用的spring容器中
     */
//    @Reference
    /*
        dubbo默认是1s超时， 默认重试2次
            在做重试业务时，一定要考虑被调用业务是否是幂等的
                幂等：多次操作结果一样
                    查询
                    删除
                    修改（设置型语句） - update 表名 set aa=12 where id =1;

                非幂等：多次操作结果不一样
                    添加
                    修改（计算型语句） - update 表名 set aa=aa+12 where id =1;
     */

//    @Reference(timeout = 3000,retries = 0)

    /*
        负载均衡策略：
            random： 随机选一台
            ***roundrobin: 轮询选择  A:2 B:3 C:1
            leastactive: 每一次请求过来，在服务器计数都会加1，请求结束后，减少一个1.服务器计数值越小，说明服务器处理能力越强 （能者多劳）
            shortestresponse: 看那台服务器的平均响应时间最小，后续请求就倾向于给谁
            consistenthash：请求参数如果hash值一样， 那么请求都会打到同一台服务器
     */
//    @Reference(version = "2.0",loadbalance = "roundrobin",timeout = 1500)

    /*
        集群容错：在访问一个集群中机器发生错误时，如果对待这个访问错误的
            ***failover: 失败自动切换，当出现失败，重试其它服务器 (幂等业务建议使用这个值，默认值)
            ***failfast: 快速失败，只发起一次调用，失败立即报错（非幂等业务，建议使用这个值）
            failsafe: 失败安全，出现异常时，直接忽略
            failback: 失败自动恢复，后台记录失败请求，定时重发
            forking: 并行调用多个服务器，只要一个成功即返回
            broadcast: 广播调用所有提供者，逐个调用，任意一台报错则报错
     */
//    @Reference(version = "2.0",loadbalance = "roundrobin",timeout = 1500,cluster = "failfast")

      /*
            本地存根
            本地伪装--降级操作
       */
    @Reference(version = "2.0",loadbalance = "roundrobin",timeout = 1500,cluster = "failfast",
            stub = "com.qf.stub.OrderServiceStub",
            mock = "com.qf.mock.OrderServiceMock"
    )
    private OrderService orderService;

    @Override
    public List<Order> findById(Integer uid) throws InterruptedException {

        //发起RPC调用
        return orderService.findByUid(uid);
    }
}
